/*
 * @(#) $Header$
 *
 * Copyright (C) 2011  Daniel Léonard
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 */

package ca.forklabs.baselib.util;

import java.text.CollationKey;
import java.text.Collator;
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;
import java.util.Locale;
import java.util.Set;
import java.util.TreeSet;

/**
 * Class {@code StringUtil} provides useful methods acting on strings.
 *
 * @author   <a href="mailto:forklabs at gmail.com?subject=ca.forklabs.util.StringUtil">Daniel Léonard</a>
 * @version $Revision$
 */
public class StringUtil {

//---------------------------
// Constructor
//---------------------------

   /**
    * Only allow subclass factories.
    */
   protected StringUtil() {
   // nothing
      }


//---------------------------
// Class methods
//---------------------------

   /**
    * Sorts a list of {@link String}s using the primary rules of the
    * {@link Locale}.
    * @param   strings   the list of string.
    * @param   locale   the locale of the underlying collator.
    * @return   a new list containing all the string sorted.
    * @see   java.text.Collator#PRIMARY
    */
   public static List<String> sort(List<String> strings, Locale locale) {
      Collator collator = Collator.getInstance(locale);

      int strength = Collator.PRIMARY;
      collator.setStrength(strength);

      List<String> sorted = sort(strings, collator);
      return sorted;
      }

   /**
    * Sorts a list of {@link String}s according to the rules of the
    * {@link Collator} and its underlying {@link CollationKey}.
    * @param   strings   the list of string.
    * @param   collator   the collator.
    * @return   a new list containing all the string sorted.
    */
   public static List<String> sort(List<String> strings, Collator collator) {
      final Collator the_collator = collator;

      Set<CollationKey> keys = new TreeSet<>();
      Algorithm.transform(strings, Iterators.backInserter(keys), new UnaryFunction<CollationKey, String>() {
         @Override
         public CollationKey invoke(String string) {
            CollationKey key = the_collator.getCollationKey(string);
            return key;
            }
         });

      List<String> sorted = new LinkedList<>();
      Algorithm.transform(keys, Iterators.backInserter(sorted), new UnaryFunction<String, CollationKey>() {
         @Override
         public String invoke(CollationKey key) {
            String string = key.getSourceString();
            return string;
            }
         });

      return sorted;
      }

   /**
    * Determines if the string is blank. A string is blank if it is {@code null}
    * or if it composed of only whitespaces.
    * @param   s   the string to evaluate.
    * @return   {@code true} if the string is blank, {@code false} otherwise.
    * @see   Character#isWhitespace(char)
    */
   public static boolean isBlank(String s) {
      boolean is_blank = true;

   // make sure that a null string is treated as an empty string
      s = (null == s) ? "" : s; //$NON-NLS-1$
      for (int i = 0, len = s.length(); is_blank && (i < len); i++) {
         char c = s.charAt(i);
         is_blank = Character.isWhitespace(c);
         }

      return is_blank;
      }

   /**
    * Joins the string representation of each object separated by the delimiter.
    * @param   delim   the delimiter.
    * @param   collection   the collection.
    * @return   the joined string.
    */
   public static String join(String delim, Collection<?> collection) {
      Object[] data = collection.toArray(new Object[0]);
      String join = join(delim, data);
      return join;
      }

   /**
    * Joins the string representation of each object separated by the delimiter.
    * @param   delim   the delimiter.
    * @param   data   the data.
    * @return   the joined string.
    */
   public static String join(String delim, Object... data) {
      StringBuilder sb = new StringBuilder();
      for (int i = 0, len = data.length; i < len; i++) {
         sb.append(data[i]);
         if (i >= len - 1) {
            break;
            }
         sb.append(delim);
         }
      String join = sb.toString();
      return join;
      }

   }
